from typing import Any, Dict, List, Optional, Union

from pydantic import AnyHttpUrl, EmailStr, HttpUrl, PostgresDsn, validator
from pydantic_settings import BaseSettings


class Settings(BaseSettings):
    """应用程序配置类
    
    包含应用程序所有配置项，使用pydantic进行类型验证和环境变量加载
    """
    # 基本配置
    PROJECT_NAME: str = "0code"  # 项目名称
    API_V1_STR: str = "/api/v1"  # API前缀路径
    SECRET_KEY: str = "your-secret-key-here"  # JWT加密密钥，生产环境中必须更改
    ACCESS_TOKEN_EXPIRE_MINUTES: int = 60 * 24 * 8  # 访问令牌过期时间（分钟），默认8天

    # CORS配置
    BACKEND_CORS_ORIGINS: List[AnyHttpUrl] = []  # 允许的CORS来源列表

    @validator("BACKEND_CORS_ORIGINS", pre=True)
    def assemble_cors_origins(cls, v: Union[str, List[str]]) -> Union[List[str], str]:
        """验证并处理CORS来源配置
        
        支持从字符串（逗号分隔）或列表格式转换为列表格式
        
        Args:
            v: 原始CORS配置值
            
        Returns:
            处理后的CORS配置列表
            
        Raises:
            ValueError: 当输入格式不正确时抛出
        """
        if isinstance(v, str) and not v.startswith("["):
            return [i.strip() for i in v.split(",")]
        elif isinstance(v, (list, str)):
            return v
        raise ValueError(v)

    # 数据库类型配置
    DB_TYPE: str = "mysql"  # 数据库类型，支持postgresql、mysql、sqlite
    
    # PostgreSQL配置
    POSTGRES_SERVER: str = "localhost"  # PostgreSQL服务器地址
    POSTGRES_USER: str = "postgres"  # PostgreSQL用户名
    POSTGRES_PASSWORD: str = "postgres"  # PostgreSQL密码
    POSTGRES_DB: str = "app"  # PostgreSQL数据库名
    SQLALCHEMY_DATABASE_URI: Optional[PostgresDsn] = None  # SQLAlchemy数据库连接URI
    
    # MySQL配置
    MYSQL_SERVER: str = "localhost"  # MySQL服务器地址
    MYSQL_PORT: int = 3306  # MySQL服务器端口
    MYSQL_USER: str = "root"  # MySQL用户名
    MYSQL_PASSWORD: str = "0code"  # MySQL密码
    MYSQL_DB: str = "app"  # MySQL数据库名
    MYSQL_DATABASE_URI: str = "mysql+pymysql://root:0code@localhost:3306/app"  # MySQL数据库连接URI
    
    # SQLite配置
    SQLITE_DATABASE_URI: str = "sqlite:///./app.db"  # SQLite数据库文件路径

    @validator("SQLALCHEMY_DATABASE_URI", pre=True)
    def assemble_postgres_connection(cls, v: Optional[str], values: Dict[str, Any]) -> Any:
        """构建PostgreSQL数据库连接URI
        
        如果未直接提供URI，则根据各个配置项构建完整的PostgreSQL连接URI
        
        Args:
            v: 原始数据库URI值
            values: 当前配置类中的所有值
            
        Returns:
            构建好的数据库连接URI
        """
        if isinstance(v, str):
            return v
        return PostgresDsn.build(
            scheme="postgresql",
            username=values.get("POSTGRES_USER"),
            password=values.get("POSTGRES_PASSWORD"),
            host=values.get("POSTGRES_SERVER"),
            path=f"/{values.get('POSTGRES_DB') or ''}"
        )
        
    @validator("MYSQL_DATABASE_URI", pre=True)
    def assemble_mysql_connection(cls, v: Optional[str], values: Dict[str, Any]) -> Any:
        """构建MySQL数据库连接URI
        
        如果未直接提供URI，则根据各个配置项构建完整的MySQL连接URI
        
        Args:
            v: 原始数据库URI值
            values: 当前配置类中的所有值
            
        Returns:
            构建好的数据库连接URI
        """
        if isinstance(v, str):
            return v
        return f"mysql+pymysql://{values.get('MYSQL_USER')}:{values.get('MYSQL_PASSWORD')}@{values.get('MYSQL_SERVER')}:{values.get('MYSQL_PORT')}/{values.get('MYSQL_DB') or ''}"


    # Redis配置
    REDIS_HOST: str = "localhost"  # Redis服务器地址
    REDIS_PORT: int = 6379  # Redis服务器端口
    REDIS_DB: int = 0  # Redis数据库索引
    REDIS_PASSWORD: Optional[str] = None  # Redis密码，如不需要认证则为None

    # RabbitMQ配置
    RABBITMQ_HOST: str = "localhost"  # RabbitMQ服务器地址
    RABBITMQ_PORT: int = 5672  # RabbitMQ服务器端口
    RABBITMQ_USER: str = "guest"  # RabbitMQ用户名
    RABBITMQ_PASSWORD: str = "guest"  # RabbitMQ密码
    RABBITMQ_VHOST: str = "/"  # RabbitMQ虚拟主机

    class Config:
        """Pydantic配置类
        
        控制Settings类的行为
        """
        case_sensitive = True  # 配置键名区分大小写
        env_file = ".env"  # 从.env文件加载环境变量


# 创建全局配置实例
settings = Settings()